﻿package frEngine.loaders.away3dMd5
{
    import __AS3__.vec.*;
    import flash.events.*;
    import flash.geom.*;
    import frEngine.*;
    import frEngine.core.*;
    import frEngine.event.*;
    import frEngine.loaders.resource.info.*;

    public class SkeletonAnimator extends EventDispatcher
    {
        private var indentyMatrix:Matrix3D;
        public var curActionTrack:SkeletonClipNode;
        public var fileName:String;
        public var skeletonInfo:SkeletonInfo;
        private var _jointsPerVertex:uint;
        private var skeletonPose:SkeletonPose;
        private var _hasDipspose:Boolean = false;
        private var _frame:int = 0;
        private static var _templeVector3d:Vector3D = new Vector3D();

        public function SkeletonAnimator(param1:SkeletonInfo)
        {
            this.indentyMatrix = new Matrix3D();
            this.skeletonInfo = param1;
            this.fileName = this.skeletonInfo.name;
            this.skeletonInfo.userList[this] = true;
            return;
        }// end function

        public function get animationSet() : SkeletonAnimationSet
        {
            return this.skeletonInfo.mainParser.animationSet;
        }// end function

        public function getGlobalMatrices(param1:String, param2:int, param3:Vector.<int>, param4:Skeleton) : Vector.<Number>
        {
            if (this.curActionTrack.trackName != param1)
            {
                this.play(param1, param2);
            }
            else
            {
                this.skeletonPose = this.curActionTrack.getGloblePoses(param2);
            }
            return this.skeletonPose.getGlobalProperties(param4, param3);
        }// end function

        public function play(param1:String, param2:int) : void
        {
            if (!this.animationSet.hasAnimation(param1))
            {
                this.curActionTrack = null;
                this.skeletonPose = null;
                return;
            }
            this.curActionTrack = this.animationSet.getAnimation(param1) as SkeletonClipNode;
            if (!this.curActionTrack)
            {
                throw new Error("动作不存在！");
            }
            if (!this.curActionTrack.hasLoaded && !this.curActionTrack.isInHead)
            {
                if (this.skeletonInfo.subSkeletonMap[this.curActionTrack.trackName] == null)
                {
                    this.skeletonInfo.loadSubSkeleton(this.curActionTrack.trackName);
                }
                FrEventDispatcher.instance.proxyAddEventListener(this.curActionTrack, Engine3dEventName.TRACK_LOADED, this.actionLoadedHander);
            }
            else
            {
                this.updateFrame(param2);
            }
            return;
        }// end function

        public function getSwordLightSurface(param1:int, param2:int, param3:int, param4:int, param5:Vector3D) : SwordLightSurface
        {
            if (param1 == -1 || !this.curActionTrack || !this.curActionTrack.hasLoaded)
            {
                return null;
            }
            return this.curActionTrack.getBoneSwordLightSurface(param1, param2, param3, param4, param5);
        }// end function

        public function getGMatrix3DByIndex(param1:int, param2:Matrix3D) : Boolean
        {
            if (param1 == -1 || !this.curActionTrack || !this.curActionTrack.hasLoaded || !this.skeletonPose)
            {
                return false;
            }
            this.skeletonPose.jointPoseFromIndex(param1, param2, null);
            return true;
        }// end function

        public function getGJointPoseByIndex(param1:int) : Vector3D
        {
            if (param1 == -1 || !this.skeletonPose)
            {
                return null;
            }
            this.skeletonPose.jointPoseFromIndex(param1, null, _templeVector3d);
            return _templeVector3d;
        }// end function

        private function actionLoadedHander(event:Event) : void
        {
            var _loc_2:SkeletonClipNode = null;
            FrEventDispatcher.instance.proxyRemoveEventListener(_loc_2, Engine3dEventName.TRACK_LOADED, this.actionLoadedHander);
            _loc_2 = event.currentTarget as SkeletonClipNode;
            if (this.curActionTrack && this.curActionTrack.trackName == _loc_2.trackName)
            {
                this.updateFrame(this._frame);
                FrEventDispatcher.instance.proxyDispatchEvent(this, Engine3dEventName.TRACK_PARSERCOMPLETE, [_loc_2]);
            }
            return;
        }// end function

        public function dispose() : void
        {
            if (this.curActionTrack)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(this.curActionTrack, Engine3dEventName.TRACK_LOADED, this.actionLoadedHander);
                this.curActionTrack = null;
            }
            this.skeletonPose = null;
            this._hasDipspose = true;
            if (this.skeletonInfo)
            {
                delete this.skeletonInfo.userList[this];
                this.skeletonInfo = null;
            }
            FrEventDispatcher.instance.removeAllProxyEventListener(this);
            return;
        }// end function

        public function updateFrame(param1:int) : void
        {
            if (this.skeletonInfo.needReload && !this.skeletonInfo.isLoaded)
            {
                this.skeletonInfo.reload();
                this.skeletonInfo.needReload = false;
            }
            if (!this._hasDipspose && !this.curActionTrack)
            {
                this.skeletonPose = null;
                return;
            }
            if (this.curActionTrack.hasLoaded)
            {
                this._frame = param1;
                this.skeletonPose = this.curActionTrack.getGloblePoses(param1);
            }
            return;
        }// end function

    }
}
